/**
 * Copyright (C) 2008 aileron.cc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package cc.aileron.mail.sender.system;

import static cc.aileron.commons.utility.ResourceUtils.resource;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;

import cc.aileron.commons.accessor.PojoAccessor;
import cc.aileron.commons.accessor.PojoAccessorModule;
import cc.aileron.commons.utility.InjectorUtils;
import cc.aileron.mail.sender.MailSender;
import cc.aileron.mail.sender.MailTo;
import cc.aileron.mail.sender.gmail.GMailAccount;
import cc.aileron.mail.sender.gmail.GMailSenderModule;
import cc.aileron.mail.sender.smtp.SmtpAccount;
import cc.aileron.mail.sender.smtp.SmtpSenderModule;

import com.google.inject.Module;

/**
 * Senderの種別
 * 
 * @author Aileron
 * 
 */
public enum SystemMailSender
{
    /**
     * G-MAIL送信用
     */
    GMAIL(GMailSenderModule.class, GMailAccount.class)

    /**
     * SMTP送信用
     */
    , SMTP(SmtpSenderModule.class, SmtpAccount.class);

    /**
     * メール送信を行なう
     * 
     * @param properties
     * @throws Exception
     */
    public void execute(final Properties properties) throws Exception
    {
        final MailSender mailSender = getSender(properties);
        final MailTo to = new MailTo();
        to.subject = properties.getProperty("subject");
        to.text = properties.getProperty("text");
        to.to = properties.getProperty("to", "").split(",");
        to.cc = properties.getProperty("cc", "").split(",");
        to.bcc = properties.getProperty("bcc", "").split(",");

        to.file = new ArrayList<File>();
        for (final String fileName : properties.getProperty("file", "").split(
                ","))
        {
            if (!StringUtils.isEmpty(fileName))
            {
                to.file.add(new File(resource(fileName).toURL().toURI()));
            }
        }
        mailSender.sendMail(to);
    }

    /**
     * get MailSender
     * 
     * @param p
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws SecurityException
     * @throws InvocationTargetException
     */
    private MailSender getSender(final Properties p)
            throws InstantiationException, IllegalAccessException,
            IllegalArgumentException, SecurityException,
            InvocationTargetException
    {
        final PojoAccessor<?> pojo = PojoAccessorModule.defaultFactory
                .accessor(parameter.newInstance());
        switch (this)
        {
        case GMAIL:
            pojo.set("user", p.get("user"));
            pojo.set("pass", p.get("pass"));
            break;

        case SMTP:
            pojo.set("localHost", p.get("localhost"));
            pojo.set("smtpHost", p.get("host"));
            pojo.set("fromAddress", p.get("from"));
            break;
        }
        final Module module = (Module) moduleClass.getConstructors()[0]
                .newInstance(pojo.toTarget());
        return InjectorUtils.createInjector(module, MailSender.class);
    }

    /**
     * constractor set fields
     * 
     * @param moduleClass
     * @param parameter
     */
    private SystemMailSender(final Class<? extends Module> moduleClass,
            final Class<?> parameter)
    {
        this.moduleClass = moduleClass;
        this.parameter = parameter;
    }

    /**
     * parameter
     */
    private final Class<?> parameter;

    /**
     * module-class
     */
    private final Class<? extends Module> moduleClass;
}
